package cn.daniellee.plugin.ce.component;

import cn.daniellee.plugin.ce.CraftEconomy;
import cn.daniellee.plugin.ce.model.PlayerData;
import com.google.common.collect.Iterables;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import net.milkbowl.vault.economy.AbstractEconomy;
import net.milkbowl.vault.economy.EconomyResponse;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;

public class VaultAPI extends AbstractEconomy {

	@Override
	public boolean isEnabled() {
		return true;
	}

	@Override
	public String getName() {
		return "CraftEconomy";
	}

	@Override
	public boolean hasBankSupport() {
		return false;
	}

	@Override
	public int fractionalDigits() {
		return -1;
	}

	@Override
	public String format(double amount) {
		return String.valueOf(amount);
	}

	@Override
	public String currencyNamePlural() {
		return "Coins";
	}

	@Override
	public String currencyNameSingular() {
		return "Coin";
	}

	@Override
	public boolean hasAccount(String name) {
		if (CraftEconomy.getInstance().isOnlineMode()) {
			name = Bukkit.getOfflinePlayer(name).getUniqueId().toString();
		}
		CraftEconomy.getInstance().getStorage().refreshPlayerData(name);
		return true;
	}

	@Override
	public boolean hasAccount(String name, String world) {
		return hasAccount(name);
	}

	@Override
	public double getBalance(String name) {
		if (CraftEconomy.getInstance().isOnlineMode()) {
			name = Bukkit.getOfflinePlayer(name).getUniqueId().toString();
		}
		PlayerData playerData = CraftEconomy.getInstance().getStorage().getPlayerData(name);
		return playerData != null ? playerData.getBalance() : 0;
	}

	@Override
	public double getBalance(String name, String world) {
		return getBalance(name);
	}

	@Override
	public boolean has(String name, double amount) {
		return getBalance(name) >= amount;
	}

	@Override
	public boolean has(String name, String world, double amount) {
		return has(name, amount);
	}

	@Override
	public EconomyResponse withdrawPlayer(String name, double amount) {
		double balance = getBalance(name);
		if (balance < amount) {
			return new EconomyResponse(0.0D, balance, EconomyResponse.ResponseType.FAILURE, "The value is more than the player's balance!");
		}
		balance = new BigDecimal(balance).subtract(new BigDecimal(amount)).doubleValue();
		if (CraftEconomy.getInstance().isOnlineMode()) {
			name = Bukkit.getOfflinePlayer(name).getUniqueId().toString();
		}
		CraftEconomy.getInstance().getStorage().updatePlayerData(name, "balance", balance);
		// 发送BC消息
		sendUpdateMessage(name, -amount);
		return new EconomyResponse(amount, balance, EconomyResponse.ResponseType.SUCCESS, "");
	}

	@Override
	public EconomyResponse withdrawPlayer(String name, String world, double amount) {
		return withdrawPlayer(name, amount);
	}

	@Override
	public EconomyResponse depositPlayer(String name, double amount) {
		double balance = getBalance(name);
		balance = new BigDecimal(balance).add(new BigDecimal(amount)).doubleValue();
		if (CraftEconomy.getInstance().isOnlineMode()) {
			name = Bukkit.getOfflinePlayer(name).getUniqueId().toString();
		}
		CraftEconomy.getInstance().getStorage().updatePlayerData(name, "balance", balance);
		// 发送BC消息
		sendUpdateMessage(name, amount);
		return new EconomyResponse(amount, balance, EconomyResponse.ResponseType.SUCCESS, "");
	}

	/**
	 * 发送BC消息
	 * @param name
	 */
	private void sendUpdateMessage(String name, double amount) {
		if (CraftEconomy.getInstance().isBungeecord()) {
			ByteArrayDataOutput out = ByteStreams.newDataOutput();
			out.writeUTF("Forward");
			out.writeUTF("ALL");
			out.writeUTF("CraftEconomy");
			ByteArrayOutputStream msgBytes = new ByteArrayOutputStream();
			DataOutputStream msgOut = new DataOutputStream(msgBytes);
			try {
				msgOut.writeUTF("Update");
				msgOut.writeUTF(name);
				msgOut.writeDouble(amount);
			} catch (IOException ignored) { }
			out.writeShort(msgBytes.toByteArray().length);
			out.write(msgBytes.toByteArray());
			Player player = Iterables.getFirst(Bukkit.getOnlinePlayers(), null);
			if (player != null) {
				player.sendPluginMessage(CraftEconomy.getInstance(), "BungeeCord", out.toByteArray());
			}
		}
	}

	@Override
	public EconomyResponse depositPlayer(String name, String world, double amount) {
		return depositPlayer(name, amount);
	}

	@Override
	public EconomyResponse createBank(String s, String s1) {
		return null;
	}

	@Override
	public EconomyResponse deleteBank(String s) {
		return null;
	}

	@Override
	public EconomyResponse bankBalance(String s) {
		return null;
	}

	@Override
	public EconomyResponse bankHas(String s, double v) {
		return null;
	}

	@Override
	public EconomyResponse bankWithdraw(String s, double v) {
		return null;
	}

	@Override
	public EconomyResponse bankDeposit(String s, double v) {
		return null;
	}

	@Override
	public EconomyResponse isBankOwner(String s, String s1) {
		return null;
	}

	@Override
	public EconomyResponse isBankMember(String s, String s1) {
		return null;
	}

	@Override
	public List<String> getBanks() {
		return null;
	}

	@Override
	public boolean createPlayerAccount(String name) {
		return hasAccount(name);
	}

	@Override
	public boolean createPlayerAccount(String name, String world) {
		return createPlayerAccount(name);
	}

}
